Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(content-serve): delegate with token caveat #1603

Closed
wants to merge 2 commits into from

Conversation

fforbeck
Copy link
Member

@fforbeck fforbeck commented Dec 9, 2024

Context

We should enable setting a token when delegating the space/content/serve/* capability. This would allow us to validate the token included in gateway requests and determine whether to serve the content based on the validation result.

Related Issues

@fforbeck fforbeck requested review from Peeja and alanshaw December 9, 2024 15:17
@fforbeck fforbeck self-assigned this Dec 9, 2024
Peeja
Peeja previously requested changes Dec 9, 2024
Copy link
Member

@Peeja Peeja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I think the issues coming from CI are because options itself is optional and doesn't have a default; you may need to give it a default of {} for the case where it's not provided at all.

packages/capabilities/src/space.js Outdated Show resolved Hide resolved
@fforbeck fforbeck changed the title feat(content-serve): delegate with auth token caveat feat(content-serve): delegate with token caveat Dec 9, 2024
@fforbeck fforbeck requested a review from Peeja December 9, 2024 17:13
@fforbeck fforbeck force-pushed the feat/content-serve-auth-token branch from ca9ab26 to e804824 Compare December 9, 2024 17:47
@fforbeck fforbeck force-pushed the feat/content-serve-auth-token branch from e804824 to 3f76be3 Compare December 9, 2024 17:49
@fforbeck fforbeck dismissed Peeja’s stale review December 9, 2024 22:14

Waiting for another review.

@fforbeck fforbeck requested a review from travis December 9, 2024 23:06
Copy link
Member

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's a good idea to set the token on the wildcard capability.

What if a space/content/serve/* delegation is required for the gateway to serve data and record egress at all. That means that it is up to the service to decide the terms for rate limiting, which may be extremely restrictive eventually.

If you (the user) wants to lift those restrictions or manage your own restrictons you'd also delegate a more specific non-wildcard capability (space/content/serve/http) with a token (and eventually other optional restrictions, like CID, or IP address or referer for example).

I think this is preferable, because the user will want to create and revoke multiple access tokens, without removing the ability for the gateway to serve data / record egress in general.

You'd then perhaps manage tokens in the client like:

interface Client {
  // ... existing methods

  // Calls `access/delegate` with `space/content/serve/http`, allowing access with a user defined token and
  // eventually rate limiting or other restrictions set by the user.
  // Options allows the service to authorize to be customized, defaulting to w3s.link.
  authorizeContentServeHTTP(restrictions: { token: string }, options: Options): Promise<Result<Delegation>>

  // Calls `ucan/revoke` for the given delegation.
  // Options allows the service to authorize to be customized, defaulting to w3s.link.
  revokeContentServe(delegation: Link, options: Options): Promise<Result<Unit, DelegationNotFound>>
}

So, the createSpace function would do what it does currently - delegate space/content/serve/* to enable general access and egress accounting, but for managing tokens you'd use the new methods.

On the server you can then have a KV mapping of spaceDID+token: delegation which you can query to determine if token access is allowed for a space.

with: SpaceDID,
nb: Schema.struct({
/** The authorization token, if any, used for this request. */
token: Schema.string().nullable(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this defined at this level?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that defining it at the top level could be overly restrictive. Allowing its use within the transport/http capability seems like a good approach, as it enables revocation without affecting the ability to serve content or record egress. @Peeja, what are your thoughts on this?

* [IPFS Gateway]: https://specs.ipfs.tech/http-gateways/path-gateway/
*/
export const transportHttp = capability({
can: 'space/content/serve/transport/http',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDK if "transport" is useful, makes it very verbose.

Suggestion: space/content/serve/http

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I'm not sure now who originally proposed transport and why, but I don't think there was strong reasoning that went with it as much as putting something down.

@fforbeck
Copy link
Member Author

Closing this PR for now. Any proposals for handling tokens will be tracked in issue #213.

@fforbeck fforbeck closed this Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants